#ifndef PROG_H
#define PROG_H
#include "lex.h"
#include <vector>
#include <stack>
using namespace std;
class prog
{
    vector<lex> vlex;
    stack<int> st_labels;
    bool finalized;
public:
    prog();
    void enq(const lex &t) {
        if (t.get_type() == POLIZ_FJMP || t.get_type() == POLIZ_JMP) {
            lex p(POLIZ_LABEL, -1);
            vlex.push_back(p);
            st_labels.push(vlex.size() - 1);
        }
        vlex.push_back(t);
    }



    void set_addr(int addr = -1) // jump to next instruction
    {
        if (addr == - 1) {
            vlex[st_labels.top()].set_value(vlex.size());
        } else {
            vlex[st_labels.top()].set_value(addr);
        }
        st_labels.pop();
    }
    friend void convert_idents(prog &p, int laddr, int raddr) {
        if (laddr < 0 || raddr < 0) {
            throw string("Baka neko");
        }

        for (int i = laddr; i < raddr; i++) {
            if (p[i].get_type() == LEX_IDENT) {
                p[i].set_type(POLIZ_ADDR);
            }
        }
    }

    void finalize() {
        if (st_labels.size()) {
            throw string("Akumonogatari");
        }
        finalized = true;
    }

    lex& operator[](int id) {
        if (id < 0 && id > size()) {
            throw string("Baka baka");
        }
        return vlex[id];
    }

    int size() const {
        return (int)vlex.size();
    }

};

#endif // PROG_H
